package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.annotation.AutoFill;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.BaseException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.*;
import com.sky.properties.DistanceProperties;
import com.sky.result.PageResult;
import com.sky.service.OrdersService;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import static com.sky.utils.DistanceUtil.countDistance;

@Service
@Slf4j
public class OrdersServiceImpl implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper ;

    @Autowired
     private UserMapper userMapper;

    @Autowired
    private AddressBookMapper addressBookMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private DistanceProperties distanceProperties;

    @Autowired
    private WebSocketServer webSocketServer;


    /**
     * 订单提交
     * @param ordersSubmitDTO
     * @return
     */
    @Transactional
    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {

        //封装起点地址
        Map<String, String> start = new HashMap<>();
        start.put("address",distanceProperties.getStartAddress());
        //封装终点地址
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        String endAddress = addressBook.getProvinceName() + addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail();
        Map<String, String> end = new HashMap<>();
        end.put("address",endAddress);
        //计算距离
        Integer distance =  countDistance(start, end, distanceProperties.getAk());
        if (distance > distanceProperties.getFasterDistance()){
            throw new BaseException(MessageConstant.DISTANCE_TO_FALL);
        }

        //订单数据封装
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO,orders);
        String number = String.valueOf(System.currentTimeMillis());
        orders.setNumber(number);
        orders.setStatus(orders.PENDING_PAYMENT);
        Long userId = BaseContext.getCurrentId();
        orders.setUserId(userId);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(orders.UN_PAID);

        User user = userMapper.searchUserById(orders.getUserId());
        orders.setUserName(user.getName());

        AddressBook addressBook2 = addressBookMapper.getById(orders.getAddressBookId());
        if (addressBook2 == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        orders.setPhone(addressBook2.getPhone());
        orders.setAddress(addressBook2.getDetail());//详细地址就行
        orders.setConsignee(addressBook2.getConsignee());

        //新增订单信息
        ordersMapper.submit(orders);
        Long id = orders.getId();

        //订单详细数据封装
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.searchBy(shoppingCart);
        if (shoppingCarts == null || shoppingCarts.size() == 0) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        List<OrderDetail> orderDetails = new ArrayList<>();
        for (ShoppingCart cart : shoppingCarts) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart,orderDetail , "id");
            orderDetail.setOrderId(id);
            orderDetails.add(orderDetail);
        }
        //新增订单详细数据
        orderDetailMapper.insertOrderDetails(orderDetails);

        //封装返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder().
                id(id).orderAmount(orders.getAmount()).
                orderNumber(number).
                orderTime(orders.getOrderTime()).build();

        shoppingCartMapper.clean(shoppingCart);
        return orderSubmitVO;

    }

    /**
     * 订单支付
     *
     * @param ordersPaymentDTO
     * @return
     */
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
//        // 当前登录用户id
//        Long userId = BaseContext.getCurrentId();
//        User user = userMapper.searchUserById(userId);
//
//        //调用微信支付接口，生成预支付交易单
//        JSONObject jsonObject = weChatPayUtil.pay(
//                ordersPaymentDTO.getOrderNumber(), //商户订单号
//                new BigDecimal(0.01), //支付金额，单位 元
//                "苍穹外卖订单", //商品描述
//                user.getOpenid() //微信用户的openid
//        );
//
//        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
//            throw new OrderBusinessException("该订单已支付");
//        }
//
//        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
//        vo.setPackageStr(jsonObject.getString("package"));
////        return vo;//返回给前端的预支付交易单

        //直接在这改状态，本来是第13步，微信发送回调请求后才改的状态。
        paySuccess(ordersPaymentDTO.getOrderNumber());
        return new OrderPaymentVO();
    }

    /**
     * 支付成功，修改订单状态
     *
     * @param outTradeNo
     */
    public void paySuccess(String outTradeNo) {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();

        // 根据订单号查询当前用户的订单
        Orders ordersDB = ordersMapper.getByNumberAndUserId(outTradeNo, userId);

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();

        ordersMapper.update(orders);
        Map map = new HashMap();
        map.put("type",1);
        map.put("orderId",orders.getId());
        map.put("content","订单号：" + outTradeNo);
        String jsonString = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(jsonString);
    }

    /**
     * 查询历史订单
     * @param queryDTO
     * @return
     */
    @Override
    public PageResult searchHistoryOrders(OrdersPageQueryDTO queryDTO) {
        PageHelper.startPage(queryDTO.getPage(),queryDTO.getPageSize());
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();
        queryDTO.setUserId(userId);
        Page<OrderVO> page = ordersMapper.searchHistoryOrders(queryDTO);
        for (OrderVO orderVO : page) {
            List<OrderDetail> list = orderDetailMapper.searchOrderDetail(orderVO.getId());
            orderVO.setOrderDetailList(list);
        }

        return new PageResult(page.getTotal(),page.getResult());
    }

    /**
     * 查询订单详情
     * @param id
     * @return
     */
    @Override
    public OrderVO searchOrderDetailById(Long id) {
        OrderVO orderVO = ordersMapper.searchOrderById(id);
        List<OrderDetail> list = orderDetailMapper.searchOrderDetail(id);
        orderVO.setOrderDetailList(list);
        return orderVO;
    }

    /**
     * 再来一单
     *
     * @param id
     * @return
     */
    @Override
    public void repetition(Long id) {
        List<OrderDetail> orderDetails = orderDetailMapper.searchOrderDetail(id);
        if (orderDetails == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        for (OrderDetail orderDetail : orderDetails) {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail, shoppingCart);
            shoppingCart.setUserId(BaseContext.getCurrentId());
            shoppingCartMapper.add(shoppingCart);
        }

    }

    @Override
    public void reminder(Long id) {
        OrderVO orderVO = ordersMapper.searchOrderById(id);
        if(orderVO == null){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        String number = orderVO.getNumber();
        Map map = new HashMap();
        map.put("type",2);
        map.put("orderId",id);
        map.put("content","订单号：" + number);
        String jsonString = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(jsonString);

    }

    /**
     * 订单条件查询
     *
     * @param ordersPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());
        Page<OrderVO> page = ordersMapper.pageQuery(ordersPageQueryDTO);

        for (OrderVO orderVO : page) {
            List<OrderDetail> list = orderDetailMapper.searchOrderDetail(orderVO.getId());
            StringJoiner Dishes = new StringJoiner("；","【","】");
            for (OrderDetail orderDetail : list) {
                Dishes.add(orderDetail.getName()+"*"+orderDetail.getNumber());
            }
            orderVO.setOrderDishes(Dishes.toString());
        }
        return new PageResult(page.getTotal(),page.getResult());
    }

    /**
     * 订单状态统计
     *
     * @return
     */
    @Override
    public OrderStatisticsVO statistics() {
        OrderStatisticsVO vo = new OrderStatisticsVO();
        vo.setConfirmed(ordersMapper.statistics(Orders.CONFIRMED));
        vo.setToBeConfirmed(ordersMapper.statistics(Orders.TO_BE_CONFIRMED));
        vo.setDeliveryInProgress(ordersMapper.statistics(Orders.DELIVERY_IN_PROGRESS));
        return vo;

    }
    /**
     * 拒绝订单
     * @param ordersRejectionDTO
     */
    @Override
    public void rejectOrderById(OrdersRejectionDTO ordersRejectionDTO) {
        Orders orders = ordersMapper.searchOrderById(ordersRejectionDTO.getId());
        if(orders.getPayStatus().equals(Orders.PAID)){
            orders.setPayStatus(Orders.REFUND);
        }
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelTime(LocalDateTime.now());
        ordersMapper.rejectById(orders);
    }

    /**
     * 接单
     * @param ordersConfirmDTO
     */
    @Override
    public void confirmOrder(OrdersConfirmDTO ordersConfirmDTO) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersConfirmDTO,orders);
        orders.setStatus(Orders.CONFIRMED);
        ordersMapper.update(orders);
    }

    /**
     * 取消订单
     * @param ordersCancelDTO
     */
    @Override
    public void cancelOrder(OrdersCancelDTO ordersCancelDTO) {
        Orders orders = ordersMapper.searchOrderById(ordersCancelDTO.getId());
        if(orders.getPayStatus().equals(Orders.PAID)){
            orders.setPayStatus(Orders.REFUND);
        }
        BeanUtils.copyProperties(ordersCancelDTO,orders);
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelTime(LocalDateTime.now());
        ordersMapper.update(orders);

    }

    /**
     * 派送订单
     *
     * @param id
     */
    @Override
    public void delivery(Long id) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        ordersMapper.update(orders);
    }

    /**
     * 完成订单
     *
     * @param id
     * @return
     */
    @Override
    public void complete(Long id) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.COMPLETED);
        orders.setDeliveryTime(LocalDateTime.now());
        ordersMapper.update(orders);
    }

}
